package org.dromara.school.service.impl;

import cn.dev33.satoken.secure.BCrypt;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.toolkit.JoinWrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.core.enums.UserType;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.school.domain.*;
import org.dromara.school.domain.bo.TeacherDisciplineBo;
import org.dromara.school.service.IBindingSchoolsService;
import org.dromara.school.service.ICampusService;
import org.dromara.school.service.ITeacherDisciplineService;
import org.dromara.system.domain.SysUser;
import org.dromara.system.domain.bo.SysUserBo;
import org.dromara.system.service.ISysUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.dromara.school.domain.bo.TeacherBo;
import org.dromara.school.domain.vo.TeacherVo;
import org.dromara.school.mapper.TeacherMapper;
import org.dromara.school.service.ITeacherService;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 教师管理Service业务层处理
 *
 * @author fliay
 * @date 2025-05-26
 */
@RequiredArgsConstructor
@Service
public class TeacherServiceImpl extends MPJBaseServiceImpl<TeacherMapper, Teacher> implements ITeacherService {

    private final TeacherMapper baseMapper;

    private final IBindingSchoolsService bindingSchoolsService;

    private final ISysUserService sysUserService;

    private final ITeacherDisciplineService teacherDisciplineService;

    /**
     * 查询教师管理
     */
    @Override
    public TeacherVo queryById(Long teacherId){

        MPJLambdaWrapper<Teacher> teacherMPJLambdaWrapper = new MPJLambdaWrapper<Teacher>()
            .selectAll(Teacher.class)
            .eq(Teacher::getTeacherId, teacherId)
            .selectCollection(TeacherBo::getSchoolCampusId, map -> map
                .result(Campus::getCampusId))
            .leftJoin(BindingSchools.class, BindingSchools::getTeacherId, Teacher::getTeacherId)
            .leftJoin(Campus.class, Campus::getCampusId, BindingSchools::getSchoolCampusId)
            .logicDelToOn()
            ;


        MPJLambdaWrapper<Teacher> teacherMPJLambdaWrapper2 = new MPJLambdaWrapper<Teacher>()
            .eq(Teacher::getTeacherId, teacherId)
            //获取所有副学科
            .select(Teacher::getTeacherId)
            .selectCollection(TeacherBo::getSubDisciplineId, map -> map
                .result(Discipline::getDisciplineId)).isNotNull(TeacherDiscipline::getTeacherId)
            .leftJoin(TeacherDiscipline.class, TeacherDiscipline::getTeacherId, Teacher::getTeacherId).isNotNull(TeacherDiscipline::getTeacherId)
            .leftJoin(Discipline.class, Discipline::getDisciplineId, TeacherDiscipline::getDisciplineId).logicDelToOn();



        TeacherVo teacher = this.baseMapper.selectJoinOne(TeacherVo.class, teacherMPJLambdaWrapper);
        TeacherVo teacher2 = this.baseMapper.selectJoinOne(TeacherVo.class, teacherMPJLambdaWrapper2);
        if (StringUtils.isNotNull(teacher2)) {
            teacher.setSubDisciplineId(teacher2.getSubDisciplineId());
        }

        return teacher;



    }

    /**
     * 查询教师管理列表
     */
    @Override
    public TableDataInfo<TeacherVo> queryPageList(TeacherBo bo, PageQuery pageQuery) {

        MPJLambdaWrapper<Teacher> teacherMPJLambdaWrapper = JoinWrappers.lambda(Teacher.class)
            .selectAll(Teacher.class)
//                .leftJoin(BindingSchools.class, BindingSchools::getTeacherId, Teacher::getId)
//                .selectCollection(TeacherDto::getCampusNames, map -> map
//                        .result(SchoolCampus::getCampusName))
//                .leftJoin(SchoolCampus.class, SchoolCampus::getId, BindingSchools::getSchoolCampusId)
            .selectAs(Discipline::getSubjectName, TeacherVo::getSubjectName)
            .leftJoin(Discipline.class, Discipline::getDisciplineId, Teacher::getMainDisciplineId)
            .logicDelToOn();

        if (StringUtils.isNotNull(bo.getTeacherName())) {
            teacherMPJLambdaWrapper.like(Teacher::getTeacherName, bo.getTeacherName());
        }


        LoginUser loginUser = LoginHelper.getLoginUser();
        UserType userType = UserType.getUserType(loginUser.getUserType());

        List<Long> campusids = new ArrayList<Long>();
        switch (userType){
            case SYS_USER:
                if(bo.getSchoolCampusId() != null &&bo.getSchoolCampusId().size()>0){
                    campusids = bo.getSchoolCampusId();
                }
                break;
            case TEACHER:
            case SCHOOLADMIN:
                //TODO多校区后续处理
//                if(bo.getSchoolCampusId() != null &&bo.getSchoolCampusId().size()>0){
//                    campusids = bo.getSchoolCampusId();
//                }else{
//                    campusids = Arrays.asList( loginUser.getSysUser().getSchoolCampusIds().split(",")).stream().map(i -> Integer.valueOf(i)).collect(Collectors.toList());
//                }
                break;
//            case TEACHER:
//
////                if(teacherDto.getSchoolCampusId() != null &&teacherDto.getSchoolCampusId().size()>0){
////                    campusids = teacherDto.getSchoolCampusId();
////                }else{
////                    campusids = Arrays.asList( loginUser.getSysUser().getSchoolCampusIds().split(",")).stream().map(i -> Integer.valueOf(i)).collect(Collectors.toList());
////                }
//                break;
            default:
                return null;
        }

        if(campusids.size()>0){
            MPJLambdaWrapper<BindingSchools> mpjbs = JoinWrappers.lambda(BindingSchools.class)
                .select(BindingSchools::getTeacherId)
                .in(BindingSchools::getSchoolCampusId, campusids);
            List<BindingSchools> bindingSchools = this.bindingSchoolsService.selectJoinList(BindingSchools.class, mpjbs);
            if (bindingSchools != null && bindingSchools.size() > 0) {
                List<Long> tids = bindingSchools.stream().map(b -> b.getTeacherId()).collect(Collectors.toList());
                teacherMPJLambdaWrapper.in(Teacher::getTeacherId, tids);
            }else{
                teacherMPJLambdaWrapper.eq(Teacher::getTeacherId, "-1L");
            }
        }
        MPJLambdaWrapper<Teacher> getCampus = JoinWrappers.lambda(Teacher.class)
            .select(Teacher::getTeacherId)
            .leftJoin(BindingSchools.class, BindingSchools::getTeacherId, Teacher::getTeacherId)
            .selectCollection(TeacherVo::getCampusNames, map -> map
                .result(Campus::getCampusName))
            .leftJoin(Campus.class, Campus::getCampusId, BindingSchools::getSchoolCampusId).logicDelToOn();

        List<TeacherVo> teachers = baseMapper.selectJoinList(TeacherVo.class,getCampus);



        IPage<TeacherVo> ipage = baseMapper.selectJoinPage(
            new Page<TeacherVo>(pageQuery.getPageNum(), pageQuery.getPageSize()),
            TeacherVo.class, teacherMPJLambdaWrapper
        );

        TableDataInfo<TeacherVo> disciplineResult = TableDataInfo.build(ipage);

        return disciplineResult;

    }

    /**
     * 查询教师管理列表
     */
    @Override
    public List<TeacherVo> queryList(TeacherBo bo) {
        LambdaQueryWrapper<Teacher> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<Teacher> buildQueryWrapper(TeacherBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<Teacher> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getTeacherName()), Teacher::getTeacherName, bo.getTeacherName());
        lqw.eq(bo.getSex() != null, Teacher::getSex, bo.getSex());
        lqw.eq(bo.getJoinDate() != null, Teacher::getJoinDate, bo.getJoinDate());
        lqw.eq(StringUtils.isNotBlank(bo.getNation()), Teacher::getNation, bo.getNation());
        lqw.eq(StringUtils.isNotBlank(bo.getOnDutyStatus()), Teacher::getOnDutyStatus, bo.getOnDutyStatus());
        lqw.eq(StringUtils.isNotBlank(bo.getOnJobStatus()), Teacher::getOnJobStatus, bo.getOnJobStatus());
        lqw.eq(bo.getMainDisciplineId() != null, Teacher::getMainDisciplineId, bo.getMainDisciplineId());
        lqw.eq(StringUtils.isNotBlank(bo.getPosition()), Teacher::getPosition, bo.getPosition());
        lqw.eq(StringUtils.isNotBlank(bo.getTelphone()), Teacher::getTelphone, bo.getTelphone());
        lqw.eq(StringUtils.isNotBlank(bo.getProvince()), Teacher::getProvince, bo.getProvince());
        lqw.eq(StringUtils.isNotBlank(bo.getCity()), Teacher::getCity, bo.getCity());
        lqw.eq(StringUtils.isNotBlank(bo.getDistricts()), Teacher::getDistricts, bo.getDistricts());
        lqw.eq(StringUtils.isNotBlank(bo.getPassword()), Teacher::getPassword, bo.getPassword());
        return lqw;
    }

    /**
     * 新增教师管理
     */
    @Override
    @Transactional
    public Boolean insertByBo(TeacherBo bo) {
        Teacher teacher = new Teacher();
        BeanUtils.copyProperties(bo, teacher);
        //拿到所有校区id 用于保存到bingding_school表
        List<Long> schoolCampusIds = bo.getSchoolCampusId();
        getPCD(bo, teacher);
        //  teacher.setPassword(SecurityUtils.encryptPassword("teacheradmin"));
        //先保存教师信息
        baseMapper.insert(teacher);
        //创建用户
        SysUserBo sysUser = new SysUserBo();

        sysUser.setUserType(UserType.TEACHER.getUserType());
        sysUser.setUserName(teacher.getTelphone());
        sysUser.setTeacherId(teacher.getTeacherId());
        sysUser.setPhonenumber(teacher.getTelphone());
        sysUser.setNickName(teacher.getTeacherName());
        sysUser.setPassword( BCrypt.hashpw("teacheradmin"));

//        if (bo.getSchoolCampusId().size() > 0) {
//            //获取第一个校区
//            Campus schoolCampus = this.campusService.selectSchoolCampusById(Long.valueOf(bo.getSchoolCampusId().get(0)));
//            School school = this.schoolService.selectSchoolById(schoolCampus.getSchoolId());
//            sysUser.setSchoolName(school.getSchoolName());
//            sysUser.setSchoolId(school.getId());
//            List<SchoolCampus> campus = this.schoolCampusService.findSchoolCampusNamesByIds(teacherDto.getSchoolCampusId().stream().map(i -> Long.valueOf(i)).collect(Collectors.toList()));
//            List<String> campuslist = campus.stream().map(c -> c.getCampusName()).collect(Collectors.toList());
//            //多校区
//            sysUser.setSchoolCampusName(String.join(",", campuslist));
//            List<String> stringList = teacherDto.getSchoolCampusId().stream()
//                .map(String::valueOf)
//                .collect(Collectors.toList());
//            sysUser.setSchoolCampusIds(String.join(",", stringList));
//        }

        this.sysUserService.insertUser(sysUser);

        //保存绑定校区
        savebindingSchools(teacher, schoolCampusIds);
        //保存副学科信息
        saveDisciplines(teacher, bo.getSubDisciplineId());


        return true;
    }

    private void saveDisciplines(Teacher teacher, List<Long> subDiscipline) {

        if (!StringUtils.isEmpty(subDiscipline)) {

            for (Long discipline : subDiscipline) {
                TeacherDiscipline teacherDiscipline = new TeacherDiscipline();
                teacherDiscipline.setTeacherId(teacher.getTeacherId());
                teacherDiscipline.setDisciplineId(Long.valueOf(discipline));
                this.teacherDisciplineService.insert(teacherDiscipline);
            }
        }

    }

    private void savebindingSchools(Teacher teacher, List<Long> schoolCampusIds) {
        //然后在关联表保存关联表信息
        if (StringUtils.isEmpty(schoolCampusIds)) {
            throw new ServiceException("教师所属校区不能为空！");
        }
        //通过教师id获取所有该教师所属校区，如果没有找到就执行下面的新增
//        List<BindingSchools> bdTeachers = this.bindingSchoolsService.findByTeacherId(teacher.getId());
//        if(bdTeachers.size()>0){
//            //修改原有绑定数据
//            //获取修改数据中不存在的小区id
//            List<BindingSchools> delList = bdTeachers.stream().filter(i -> !schoolCampusIds.contains(i.getSchoolCampusId())).collect(Collectors.toList());
//
//
//
//        }else{
        //新增
        for (Long schoolCampusId : schoolCampusIds) {
            BindingSchools bindingsSchool = new BindingSchools();
            bindingsSchool.setTeacherId(teacher.getTeacherId());
            bindingsSchool.setSchoolCampusId(Long.valueOf(schoolCampusId));
            bindingsSchool.setType(UserType.TEACHER.getUserType());
            this.bindingSchoolsService.insert(bindingsSchool);
        }
//         }



    }

    private void getPCD(TeacherBo bo, Teacher teacher) {


        if (bo.getNativePlace() != null) {
            teacher.setProvince(bo.getNativePlace()[0]);
            teacher.setCity(bo.getNativePlace()[1]);
            teacher.setDistricts(bo.getNativePlace()[2]);
        }
    }

    /**
     * 修改教师管理
     */
    @Override
    public Boolean updateByBo(TeacherBo bo) {


        Teacher teacher = new Teacher();
        BeanUtils.copyProperties(bo, teacher);
        //拿到所有校区id 用于保存到bingding_school表
//        List<Integer> schoolCampusIds = teacherDto.getSchoolCampusId();
        getPCD(bo, teacher);
        //先保存教师信息
        baseMapper.updateById(teacher);


//修改教师信息不去修改教师的账号信息 下面的东西不需要了

        //创建用户
//        SysUserBo sysUser = new SysUserBo();
//
//        sysUser.setUserType(UserType.TEACHER.getUserType());
//        sysUser.setUserName(teacher.getTelphone());
//        sysUser.setTeacherId(teacher.getTeacherId());
//        sysUser.setPhonenumber(teacher.getTelphone());
//        sysUser.setNickName(teacher.getTeacherName());
//        sysUser.setPassword( BCrypt.hashpw("teacheradmin"));

//        if (teacherDto.getSchoolCampusId().size() > 0) {
//            //获取第一个校区
//            SchoolCampus schoolCampus = this.schoolCampusService.selectSchoolCampusById(Long.valueOf(teacherDto.getSchoolCampusId().get(0)));
//            School school = this.schoolService.selectSchoolById(schoolCampus.getSchoolId());
//            sysUser.setSchoolName(school.getSchoolName());
//            sysUser.setSchoolId(school.getId());
//            List<SchoolCampus> campus = this.schoolCampusService.findSchoolCampusNamesByIds(teacherDto.getSchoolCampusId().stream().map(i -> Long.valueOf(i)).collect(Collectors.toList()));
//            List<String> campuslist = campus.stream().map(c -> c.getCampusName()).collect(Collectors.toList());
//            //多校区
//            sysUser.setSchoolCampusName(String.join(",", campuslist));
//            List<String> stringList = teacherDto.getSchoolCampusId().stream()
//                .map(String::valueOf)
//                .collect(Collectors.toList());
//            sysUser.setSchoolCampusIds(String.join(",", stringList));
//        }
//        this.sysUserService.updateUser(sysUser);


        //根据teacherid先删除绑定表的数据
        this.bindingSchoolsService.deleteByTeacherId(teacher.getTeacherId());
        this.teacherDisciplineService.deleteByTeacherId(teacher.getTeacherId());
        savebindingSchools(teacher, bo.getSchoolCampusId());
        saveDisciplines(teacher, bo.getSubDisciplineId());

        return true;



    }



    /**
     * 批量删除教师管理
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public List<TeacherVo> findTeachers(Long schoolCampusId){

        MPJLambdaWrapper<Teacher> teacherMPJLambdaWrapper = JoinWrappers.lambda(Teacher.class)
            .selectAll(Teacher.class)
//            .leftJoin(BindingSchools.class, BindingSchools::getTeacherId, Teacher::getId)
//            .eq(BindingSchools::getSchoolCampusId, schoolCampusId)
            .logicDelToOn();
        List<TeacherVo> teachers = this.baseMapper.selectJoinList(TeacherVo.class, teacherMPJLambdaWrapper);


        //通过校区关联表 拿到老师id 再去教师表查老师信息


        return teachers;
    }

    @Override
    public Teacher selectTeacher(TeacherVo teacherVo) {
        //拼装查询条件
        LambdaQueryWrapper<Teacher> queryWrapper = new LambdaQueryWrapper<>();
        if (teacherVo != null) {
            queryWrapper.eq(StringUtils.isNotEmpty(teacherVo.getTeacherName()), Teacher::getTeacherName, teacherVo.getTeacherName());
            queryWrapper.eq(StringUtils.isNotEmpty(teacherVo.getTelphone()), Teacher::getTelphone, teacherVo.getTelphone());
        }

        return this.baseMapper.selectOne(queryWrapper);
    }
}
